# 函数：
# 作用：避免代码重复，增强代码可读性，
# 概念：是一个功能代码块，以功能为导向，一个函数分装一个功能，功能就是一个需求需求
# 之前的编程都是面向过程，函数只是跟进阶的面向过程

# 函数式编程
"""
# lst = [1, 2, 3]
#
#
# def new_len():
#     count = 0
#     for i in lst:
#         count += 1
#     print(count)
#
#
# new_len()
"""

# 函数的结构
"""
# def 关键字，告诉解释器要定义函数
# new_len 函数名，命名发法与变量一样，(字母数字下划线命名，数字不能开头，下划线命名法，见名知意)
# ()  用来传参
# : 分隔符，分割函数头和函数体，在解释器遇到: 时就不去执行函数体
# 函数体的执行需要函数的执行者
"""

# 函数的说明文档（在函数体第一行多行注释）


def func(nunber):
    """返回数字的平方"""
    print(nunber**2)


help(func)

# 高级用法，回车
def func2(a, b):
    """
    返会两参数的和
    :param a:数字
    :param b:数字
    :return : a,b之和
    """
    print(a+b)

help(func2)

# 函数的调用
"""
# 需要函数的执行者来调用
# 函数的执行者: 函数名+()
# new_len()
# 也可重复调用
# for i in range(3):
#     new_len()
"""

# 函数的返回值,返回值会返回给执行者本身
"""

# 关键字return
# 1、中断函数体(只要return执行，函数就结束运行)
# def new_len():
#     count = 0
#     for i in range(3):
#         count += 1
#     if i > 1:
#         return 10
#     return 100
#     print(count)
# print(new_len())
# 2、返回值
# (1)、没有return或有return不返回值，执行者得到的为None
# def new_len_1():
#     count = 0
#     for i in range(3):
#         count += 1
#     if i > 1:
#         return
#     print(count)
# print(new_len_1())
# (2)、返回一个值，执行者得到的是它本身，数据类型不变
# def new_len_1():
#     count = 0
#     for i in range(3):
#         count += 1
#     if i > 1:
#         return 1+2
#     print(count)
# new = new_len_1()
# print(new, type(new))

# (3)、返回多个值,执行者得到的是一个元组
# def new_len_1():
#     count = 0
#     for i in range(3):
#         count += 1
#     if i > 1:
#         return 1, '2', [3]
#     print(count)
# new = new_len_1()
# print(new, type(new))
"""


# 函数的传参(扩展函数)
"""
# 函数的作用是让函数的执行者得到值，而不是看到值，所哟在函数体中尽量不要用print
# 实参：在函数执行者括号内写的就叫实参，其本身有实际值
# 形参：充当实参和函数之间的中转站
# def new_len(a):
#     count = 0
#     for i in a:
#         count += 1
#     return count
#
#
# s = '21346468546'
# print(new_len(s))
# new_len() 与 len() 功能相同，但执行效率后者远大于前者，因为len()的源码是用C语言编写
"""

# 函数的参数
# (实参角度)
"""
# 1、位置参数(从左到右一一对应)

def info(name, height, sex,):
    print(f'姓名:{name} 性别:{sex} 身高:{height}')


info('bai', 175, '男')   # 位置参数
# 关键字参数，一一对应，可以不考虑顺序
info(name='bai', sex='男', height=180)   # 关键字参数

# 混合参数，位置参数和关键字的混合，位置参数一定在前
info('bai', 180, sex='女')
"""
# (形参角度)
"""
# 1、位置参数，与实参的位置参数一样，一一对应，顺序不能变
# 2、默认参数，经常使用的设为默认值(一定在位置参数的后面)


def info(name, height, sex='男',):
    print(f'姓名:{name} 性别:{sex} 身高:{height}')

    
info(height=180, name='nan')
"""

# 三元运算符，对于if...else...的简写
"""

def is_max(a, b):
    # if a > b:
    #     return a
    # else:
    #     return b
    return a if a > b else b    # 用三元运算代替上方的if...else...


print(is_max(3, 8))
"""
# 可变与不可变参数
"""

def func(a):
    a += a
    print(id(a))


# b = 10
b = [1, 2, 3]
print(id(b))
func(b)
print(b)
"""
# 不可变数据参数在函数体内发生改变时，就会重新申请空间来存储改变后的值,
# 可变数据类型在函数体内被改变时，内存地址是不会变得，直接在原来的内存空间中进行修改
